package com.qiaoya.nettyConnProxy;

import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.InputStream;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.util.Properties;
import com.qiaoya.deviceProxy.MsgLinkService;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.LineBasedFrameDecoder;
import io.netty.handler.codec.string.StringDecoder;

public class NettyConnProxy {

	public void linkStart() throws Exception {
		// 读取属性文件a.properties
		InputStream in;
		Properties config = new Properties();
		String propPath = MsgLinkService.class.getClassLoader().getResource("application.properties").getPath();
		in = new BufferedInputStream(new FileInputStream(propPath));
		config.load(in);
		String host = config.getProperty("mina.host");
		String port = config.getProperty("mina.port");
		in.close();
		
		EventLoopGroup bossGroup = new NioEventLoopGroup();
		EventLoopGroup workerGroup = new NioEventLoopGroup();

		try {
			/**
			 * 由于我们使用在 NIO 传输，我们 已指定 NioEventLoopGroup接受和处理新连接，指定
			 * NioServerSocketChannel 为信道类型。在此之后，我们设置本地地址是 InetSocketAddress
			 * 与所选择的端口（6）如。 服务器将绑定到此地址来监听新的连接请求。
			 */
			// ServerBootstrap对象是Netty用于启动NIO服务端的辅助启动类，目的是降低服务端开发的复杂度
			ServerBootstrap bootServer = new ServerBootstrap();
			// Set the EventLoopGroup for the parent (acceptor) and the child
			// (client).
			bootServer.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class)
					.localAddress(new InetSocketAddress(InetAddress.getByName(host), Integer.parseInt(port)))
					// 绑定I/O事件的处理类ChildChannelHandler,作用类似于Reactor模式中的Handler类
					// 主要用于处理网络I/O事件，例如记录日志，对消息进行编解码等
					.childHandler(new ChannelInitializer<SocketChannel>() {
						// 添加ServerHandler到Channel的ChannelPipeline
						// 通过ServerHandler给每一个新来的Channel初始化
						@Override
						protected void initChannel(SocketChannel ch) throws Exception {
							ch.pipeline().addLast(new LineBasedFrameDecoder(1024));  
					        ch.pipeline().addLast(new StringDecoder());
							ch.pipeline().addLast(new NettyServerHandler());
						}
					})
					.childHandler(new ChildChannelHandler());
			// 绑定监听端口，调用sync同步阻塞方法等待绑定操作完成，完成后返回ChannelFuture类似于JDK中Future
			ChannelFuture channelFuture = bootServer.bind(Integer.parseInt(port)).sync();
			// 使用sync方法进行阻塞，等待服务端链路关闭之后Main函数才退出
			channelFuture.channel().closeFuture().sync();
			System.out.println("IOT Server Starting!Netty^^^^(^^^)^^^^");
		} finally {
			// 优雅退出，释放线程池资源
			bossGroup.shutdownGracefully();
			workerGroup.shutdownGracefully();
		}
	}


}
